import React, {FunctionComponent, useState, useEffect} from "react";
import {
    Row,
    Tree,
    Col,
    Popconfirm,
    Form,
    Typography,
    message,
    Divider,
    Button,
    Input,
    Space,
    Modal,
    Tooltip
} from "antd";
import {MinusCircleOutlined, PlusOutlined, createFromIconfontCN, DownOutlined} from "@ant-design/icons";
import {connect} from "react-redux";
import {Post, Get, Delete} from "para-lib";
import XiTable from "../../components/XiTable";
import {API_CONFIG} from "../../config/api.config";
import EditableCell from "./EditableCell";

import "./index.less";

interface Item {
    _id: string;
}

const IconFont = createFromIconfontCN({
    scriptUrl: "//at.alicdn.com/t/font_2882598_n9kom3lrz4.js"
});

const Db: FunctionComponent<any> = () => {

    const [selectedTable, setSelectedTable] = useState<any>("");
    const [defaultSelectedKeys, setDefaultSelectedKeys] = useState<string[]>([]);
    const [treeData, setTreeData] = useState<any[]>([]);
    const [columns, setColumns] = useState<any[]>([]);
    const [refresh, setRefresh] = useState<any>("");
    const [form] = Form.useForm();
    const [editingKey, setEditingKey] = useState("");
    const [visible, setVisible] = useState<boolean>(false);
    const [initialValues, setInitialValues] = useState<any[]>([]);

    const onSelect = (selectedKeys: React.Key[], info: any) => {
        setSelectedTable(selectedKeys[0]);
    };

    const getTreeData = async () => {
        const {data, err} = await Get({
            url: API_CONFIG.database.table
        });
        if (err) return;
        let result = data.data;
        if (!result || result.length === 0) return;
        await setDefaultSelectedKeys([selectedTable || result[0].name]);
        if (!selectedTable) setSelectedTable(result[0].name);
        result = result.map((item: any) => {
            return {
                title: item.alias || item.name,
                key: item.name,
                icon: <IconFont type="icon-table"/>,
                children: []
            };
        });
        setTreeData(result);
    };

    const getColumns = async () => {
        const {data, err} = await Post({
            url: API_CONFIG.database.columns + selectedTable
        });
        if (err) return;
        let result = data.data;
        if (!result || result.length === 0) return;
        result = result.filter((item: string) => item !== "_id" && item !== "__v").map((item: string) => {
            return {
                title: item,
                dataIndex: item,
                key: item,
                editable: item !== "photo",
                render: (text: string) => {
                    if (text.indexOf("/uploads/") > -1 || text.indexOf("/blob/") > -1) {
                        return <img style={{width: "50px", height: "50px"}} src={text} alt=""/>;
                    } else {
                        return text;
                    }
                }
            };
        });
        setColumns(result);
    };

    const updateData = async (info: any) => {
        info.id = editingKey;
        const {err} = await Post({
            url: API_CONFIG.database.updateOne + selectedTable,
            data: info
        });
        if (err) return;
        message.success("操作成功");
        cancel();
        setRefresh(Math.random());
    };

    const insertData = async (info: any) => {
        const {err} = await Post({
            url: API_CONFIG.database.tableListOne + selectedTable,
            data: info
        });
        if (err) return;
        message.success("操作成功");
        closeDialog();
        // 新增数据之后也要重新获取表头
        await getColumns();
        setRefresh(Math.random());
    };

    const deleteData = async (key: string) => {
        const {err} = await Delete({
            url: API_CONFIG.database.deleteOne + selectedTable,
            data: {
                id: key
            }
        });
        if (err) return;
        message.success("操作成功");
        setRefresh(Math.random());
    };

    const save = async (key?: any) => {
        try {
            const row = (await form.validateFields()) as Item;
            console.log(row);
            updateData(row);
        } catch (errInfo) {
        }
    };

    const isEditing = (record: Item) => record._id === editingKey;

    const edit = (record: Partial<Item> & { _id: React.Key }) => {
        form.setFieldsValue({...record});
        setEditingKey(record._id);
    };

    const cancel = () => {
        setEditingKey("");
    };

    const addNew = () => {
        let columnsCopy = columns.filter((item: any) => item.dataIndex !== "operation" && item._id !== "operation");
        columnsCopy = columnsCopy.map((item) => {
            return {
                first: item.dataIndex
            };
        });
        setInitialValues(columnsCopy);
        setVisible(true);
    };

    const deleteTable = async () => {
        const {err} = await Delete({
            url: API_CONFIG.database.deleteTableApi + selectedTable
        });
        if (err) return;
        message.success("操作成功");
        setSelectedTable("");
        getTreeData();
    };

    const mergedColumns = React.useMemo(() => {
        let columnsCopy = columns.filter((item: any) => item.dataIndex !== "operation");
        columnsCopy.push({
            title: "操作",
            dataIndex: "operation",
            render: (_: any, record: Item) => {
                const editable = isEditing(record);
                return editable ? (
                    <span>
            <a href="javascript:;" onClick={() => save(record._id)} style={{marginRight: 8}}>
              保存
            </a>
            <a href="javascript:;" onClick={cancel}>
              取消
            </a>
          </span>
                ) : (
                    <>
                        <Tooltip title="编辑">
                            <Button type="link" shape="circle" disabled={editingKey !== ""} onClick={() => edit(record)}
                                    icon={<IconFont type="icon-bianji"/>}/>
                        </Tooltip>

                        <Divider type="vertical"/>
                        <Popconfirm title="确定删除本条数据吗？" onConfirm={() => deleteData(record._id)}>
                            <Tooltip title="删除">
                                <Button type="link" shape="circle" icon={<IconFont type="icon-shanchu1"/>}/>
                            </Tooltip>
                        </Popconfirm>
                    </>

                );
            }
        });
        return columnsCopy.map(col => {
            if (!col.editable) {
                return col;
            }
            return {
                ...col,
                onCell: (record: Item) => ({
                    record,
                    inputType: col.dataIndex === "age" ? "number" : "text",
                    dataIndex: col.dataIndex,
                    title: col.title,
                    editing: isEditing(record)
                })
            };
        });

    }, [columns, editingKey]);

    const onFinish = (values: any) => {
        const result = values.users;
        let paramsObj: any = {};
        result.forEach((item: any) => {
            paramsObj[item.first] = item.last;
        });
        insertData(paramsObj);
    };

    const closeDialog = () => {
        setVisible(false);
        setInitialValues([]);
    };

    const linkToForm = (id?: string) => {
        window.open(id ? `design.html?form=${id}` : "design.html");
    };

    useEffect(() => {
        if (selectedTable) getColumns();
        setRefresh(Math.random());
    }, [selectedTable]);

    useEffect(() => {
        getTreeData();
    }, []);

    return (
        <div className={"home"}>
            <Row className="db-container">
                <Col span={6} style={{height: "100%"}}>
                    <div className="title">资源表
                        <Tooltip title="新增">
                            <Button type="link" style={{right: "50px"}} onClick={() => linkToForm()} shape="circle"
                                    icon={<IconFont type="icon-xinjian"/>}/>
                        </Tooltip>
                        <Popconfirm title="确定删除该表吗？" onConfirm={deleteTable}>
                            <Tooltip title="删除">
                                <Button type="link" shape="circle"
                                        disabled={!selectedTable || selectedTable === "users"}
                                        icon={<IconFont type="icon-shanchu1"/>}/>
                            </Tooltip>
                        </Popconfirm>
                    </div>
                    {
                        treeData.length > 0 ? <Tree
                            showLine={true}
                            showIcon={true}
                            autoExpandParent={true}
                            onSelect={onSelect}
                            defaultSelectedKeys={defaultSelectedKeys}
                            treeData={treeData}
                            switcherIcon={<DownOutlined/>}
                        /> : <div className="empty-div">暂无数据</div>
                    }
                </Col>
                <Col span={18}>
                    <div className="title">表数据
                        <Tooltip title="新增">
                            <Button type="link" onClick={addNew} shape="circle" icon={<IconFont type="icon-biaoge"/>}/>
                        </Tooltip>

                    </div>


                    {
                        (selectedTable && mergedColumns.length > 1) && (
                            <Form form={form} component={false}>
                                <XiTable
                                    url={API_CONFIG.database.tableList + selectedTable}
                                    method={"Post"}
                                    columns={mergedColumns}
                                    refresh={refresh}
                                    components={{
                                        body: {
                                            cell: EditableCell
                                        }
                                    }}
                                    pagination={{
                                        onChange: cancel
                                    }}
                                />
                            </Form>
                        )
                    }
                </Col>
            </Row>
            <Modal
                title="新增数据"
                visible={visible}
                onOk={() => setVisible(false)}
                onCancel={() => setVisible(false)}
                footer={null}
            >
                <Form name="dynamic_form_nest_item" onFinish={onFinish} autoComplete="off"
                      initialValues={{users: initialValues}}>
                    <Form.List name="users">
                        {(fields, {add, remove}) => (
                            <>
                                {fields.map(({key, name, fieldKey, ...restField}) => (
                                    <Space key={key} style={{display: "flex", marginBottom: 8}} align="baseline">
                                        <Form.Item
                                            {...restField}
                                            name={[name, "first"]}
                                            fieldKey={[fieldKey, "first"]}
                                            rules={[{required: true, message: "该项必填"}]}
                                        >
                                            <Input placeholder="字段名"/>
                                        </Form.Item>
                                        <Form.Item
                                            {...restField}
                                            name={[name, "last"]}
                                            fieldKey={[fieldKey, "last"]}
                                            rules={[{required: true, message: "该项必填"}]}
                                        >
                                            <Input placeholder="字段值"/>
                                        </Form.Item>
                                        <MinusCircleOutlined onClick={() => remove(name)}/>
                                    </Space>
                                ))}
                                <Form.Item>
                                    <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined/>}>
                                        增加字段属性
                                    </Button>
                                </Form.Item>
                            </>
                        )}
                    </Form.List>
                    <Form.Item className="button-list">
                        <Button htmlType="reset" onClick={closeDialog}>
                            取消
                        </Button>
                        <Button type="primary" htmlType="submit">
                            提交
                        </Button>
                    </Form.Item>
                </Form>
            </Modal>
        </div>
    );
};

export default connect((state: { audit: any }) => ({}))(Db);
